package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaSeat;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import androidx.test.platform.app.InstrumentationRegistry;

import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AUTO_FAN_SETTING_HIGH;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AUTO_FAN_SETTING_HIGHER;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AUTO_FAN_SETTING_NORMAL;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AUTO_FAN_SETTING_QUIETER;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AUTO_FAN_SETTING_SILENT;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.HVAC_FUNC_AUTO_FAN_SETTING;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacAutoFanSpeedSettingTest extends VhalUnitTestBase {
    private static final String TAG = "HvacAutoFanSpeedSettingTest";
    private static int halValue_front;
    private static int halValue_second;

    private static final int HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_RIGHT;
    private static final int HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA = VehicleAreaSeat.SEAT_ROW_2_LEFT | VehicleAreaSeat.SEAT_ROW_2_CENTER | VehicleAreaSeat.SEAT_ROW_2_RIGHT;

    private static final int SERVICE_ID_CLIMATE = 112;
    private static final int OP_ID_CLIMATE = 0xc8;

    final static Object lock_front = new Object();
    final static Object lock_second = new Object();
    static IpcpClient ipcpClient = new IpcpClient();

    final static int climateAuto = 0;      //自动风量

    static IWrapper wrapper;
    private static IWrapper.IPropertyId fanSpeedAutoSetting;

    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        fanSpeedAutoSetting = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AUTO_FAN_SETTING);
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, fanSpeedAutoSetting.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig(OP_ID_CLIMATE);

    }

    @Test  //前排风量设置有效测试
    public void test01_HvacAutoFanSpeedSettingFrontAvail() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, 1, 1, climateAuto);
        delay();
        hvacAutoFanSpeedSettingAvail(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, true);
    }

    @Test  //前排风量设置无效测试
    public void test02_HvacAutoFanSpeedSettingFrontNotAvail() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, 3, 1, climateAuto);
        delay();
        hvacAutoFanSpeedSettingAvail(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, false);
    }

    @Test  //二排风量设置有效测试
    public void test03_HvacAutoFanSpeedSettingSecAvail() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, 1, 1, climateAuto);
        delay();
        hvacAutoFanSpeedSettingAvail(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, true);
    }

    @Test  //二排风量设置无效测试
    public void test04_HvacAutoFanSpeedSettingSecNotAvail() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, 3, 1, climateAuto);
        delay();
        hvacAutoFanSpeedSettingAvail(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, false);
    }

    @Test  //前排自动风量设置
    public void test05_HvacAutoFanSpeedSettingFront() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, 1, 0, climateAuto);
        delay();
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, AUTO_FAN_SETTING_QUIETER);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, AUTO_FAN_SETTING_SILENT);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, AUTO_FAN_SETTING_NORMAL);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, AUTO_FAN_SETTING_HIGH);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA, AUTO_FAN_SETTING_HIGHER);
    }

    @Test  //二排自动风量设置
    public void test06_HvacAutoFanSpeedSettingSecond() {
        prepareHvacAutoFanSpeedSettingTestEnv(HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, 1, 0, climateAuto);
        delay();
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, AUTO_FAN_SETTING_QUIETER);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, AUTO_FAN_SETTING_SILENT);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, AUTO_FAN_SETTING_NORMAL);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, AUTO_FAN_SETTING_HIGH);
        hvacAutoFanSpeedSet(fanSpeedAutoSetting.getPropertyId(), HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA, AUTO_FAN_SETTING_HIGHER);
    }

    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                if (carPropertyValue.getAreaId() == HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA) {
                    halValue_front = fanSpeedAutoSetting.getPropertyAdaptValue((int) carPropertyValue.getValue());

                    synchronized (lock_front) {
                        lock_front.notify();
                    }
                } else if (carPropertyValue.getAreaId() == HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA) {
                    halValue_second = fanSpeedAutoSetting.getPropertyAdaptValue((int) carPropertyValue.getValue());
                    synchronized (lock_second) {
                        lock_second.notify();
                    }
                }
                Log.d(TAG, "HVAC_FUNC_AUTO_FAN_SETTING onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId() + " propertyValue：" + carPropertyValue.getValue() + " AreaId is : " + carPropertyValue.getAreaId());
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait(int area) {
        try {
            if (area == HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA) {
                synchronized (lock_front) {
                    lock_front.wait(100);
                }
            } else if (area == HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA) {
                synchronized (lock_second) {
                    lock_second.wait(100);
                }
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void hvacAutoFanSpeedSettingAvail(int propId, int areaid, boolean expect) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(propId, areaid);
        Log.d(TAG, "HvacAutoFanSpeedSettingAvail  isAvail：" + isAvail + " expect：" + expect + " areaid：" + areaid);
        Assert.assertEquals(expect, isAvail);
    }

    private void hvacAutoFanSpeedSet(int propId, int areaid, int level) {
        int iRet = -1;
        Log.d(TAG, "HvacAutoFanSpeedSet set value ：" + level + " areaid：" + areaid);
        int propertyValue = fanSpeedAutoSetting.getPropertyValue(level);
        mCarPropertyMgr.setIntProperty(propId, areaid, propertyValue);
        delay();
        iRet = mCarPropertyMgr.getIntProperty(propId, areaid);
        int adaptValue = fanSpeedAutoSetting.getPropertyAdaptValue(iRet);

        Assert.assertEquals(level, adaptValue);

        lockWait(areaid);
        if (areaid == HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA) {
            Assert.assertEquals(level, halValue_front);
        } else if (areaid == HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA) {
            Assert.assertEquals(level, halValue_second);
        }
        delay();
    }

    private void prepareHvacAutoFanSpeedSettingTestEnv(int areaid, int avail, int data, int status) {
        int hvacPowerOnavail_front = 1;
        int hvacPowerData_front = 1;
        int hvacPowerOnavail_second = 1;
        int hvacPowerData_second = 1;
        String availability_power_front = "";
        String data_power_front = "";
        String availability_power_second = "";
        String data_power_second = "";
        String availability_fanSpeed = "";
        String data_fanSpeed = "";
        String status_fanSpeed = "";

        Log.d(TAG, " PrepareHvacAutoFanSpeedSettingTestEnv areaid is :" + areaid + "avail：" + avail + " data :" + data + " status :" + status);

        if (areaid == HVAC_FUNC_AUTO_FAN_SETTING_FRONT_AREA) {
            availability_fanSpeed = "paclfanlevel.availability";
            data_fanSpeed = "paclfanlevel.data";
            status_fanSpeed = "paclfanlevel.status";
            availability_power_front = "paclairctrloff.availability";
            data_power_front = "paclairctrloff.data";
            availability_power_second = "paclsecrowonoffswith.availability";
            data_power_second = "paclsecrowonoffswith.data";
        } else if (areaid == HVAC_FUNC_AUTO_FAN_SETTING_SEC_AREA) {
            availability_fanSpeed = "paclsecfanlevel.availability";
            data_fanSpeed = "paclsecfanlevel.data";
            status_fanSpeed = "paclsecfanlevel.status";
            availability_power_front = "paclairctrloff.availability";
            data_power_front = "paclairctrloff.data";
            availability_power_second = "paclsecrowonoffswith.availability";
            data_power_second = "paclsecrowonoffswith.data";
        }

        String[] config_indexs = {availability_fanSpeed, data_fanSpeed, status_fanSpeed, availability_power_front, data_power_front, availability_power_second, data_power_second};
        int[] values = {avail, data, status, hvacPowerOnavail_front, hvacPowerData_front, hvacPowerOnavail_second, hvacPowerData_second};
        ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs, values);
    }

    private static void setConfig(int OperId) {
        int climateOperId[] = {OperId};
        ipcpClient.setConfig(SERVICE_ID_CLIMATE, climateOperId);
    }
}
